#ifndef ZLBASE_DEVICE_IMONITORCONTROLBOARD_H_
#define ZLBASE_DEVICE_IMONITORCONTROLBOARD_H_

#include "zlbase/datalink/IBaseDatalink.h"
#include "zlbase/device/IDevice.h"
#include "zlbase/protocol/DeviceDefines.h"
#include "zlbase/protocol/IMonitorControlBoardProtocol.h"

namespace zl
{
namespace zlbase
{
/// \brief 监控板抽象基类
class IMonitorControlBoard : public IDevice
{
public:
    IMonitorControlBoard();
    virtual ~IMonitorControlBoard();

    /// \brief 装载与该设备相关的协议和链路对象
    virtual bool SetComponent(std::shared_ptr<IBaseDatalink> datalink,
                              std::shared_ptr<IMonitorControlBoardProtocol> protocol);

    /// \brief 获取与该设备相关的链路对象
    virtual std::shared_ptr<IBaseDatalink> GetDatalink();

    /// \brief 获取与该设备相关的协议对象
    virtual std::shared_ptr<IMonitorControlBoardProtocol> GetProtocol();

    /// 功能接口

    /// \brief 系统复位指令
    ///
    /// 通过监控板复位开门板
    /// \return 错误码
    virtual int32_t ResetSystem();

    /// \brief 复位开门板和工控机
    ///
    /// 该接口用于通过监控板复位开门板和工控机（单播指令）
    /// \return 错误码
    virtual int32_t ResetDcbAndIpc();

    /// \brief 复位开门板
    ///
    /// 该接口用于复位开门板
    /// \return 错误码
    virtual int32_t ResetDcb();

    /// \brief 检测UPS电源
    ///
    /// \param[out] supply 电源状态（0x00表示是UPS电源供电，0x01表示市电供电）
    /// \return 错误码
    virtual int32_t GetUpsPowerSupply(unsigned char &supply);

    /// \brief 查询温度
    ///
    /// 该接口用于设置指定监控板的当前温度
    /// \param[in] temperature 当前的温度值
    /// \return 错误码
    virtual int32_t GetTemperature(int32_t &temperature);

    /// \brief 设置温度阀值(单播指令)
    ///
    /// 该接口用于设置指定监控板上的温度上下限
    /// \param[in] th 为温度上限，超过此温度则自动启动风扇，反之，不启动
    /// \param[in] tl 为温度下限，低于此温度，则关闭风扇
    /// \return 错误码
    virtual int32_t SetTemperatureThreshold(int32_t th, int32_t tl);

    /// \brief 查询温度阀值
    ///
    /// 该接口用于设置指定监控板的当前温度
    /// \param[out] th 温度上限值
    /// \param[out] tl 温度下限值
    /// \return 错误码
    virtual int32_t GetTemperatureThreshold(int32_t &th, int32_t &tl);

    /// \brief 启动/关闭风扇
    ///
    /// 该接口用于设置指定监控板上的风扇启停
    /// \param[in] flag 启用/关闭标记（0x01：启动风扇，0x00：闭风扇）
    /// \return 错误码
    virtual int32_t EnableFan(unsigned char flag);

    /// \brief 查询风扇转速
    ///
    /// 该接口用于设置指定监控板的当前温度
    /// \param[out] speed 风扇转速，单位为转/每分
    /// \return 错误码
    virtual int32_t GetFanSpeed(int32_t &speed);

    /// \brief 查询风扇是否正常工作
    ///
    /// 该接口用于设置指定监控板的当前温度
    /// \param[out] speed 风扇转速，单位为转/每分
    /// \param[out] status 风扇状态（0x00：工作不正常，0x01：工作正常）
    /// \return 错误码
    virtual int32_t GetFanStatus(int32_t &speed, unsigned char &status);

    /// \brief 查询风扇1是否正常工作
    ///
    /// 该接口用于设置指定监控板的风扇1速度和状态，部分设备有两个风扇，若只有一个风扇时应调用GetFanStatus接口
    /// \param[out] speed 风扇转速，单位为转/每分
    /// \param[out] status 风扇状态（0x00：工作不正常，0x01：工作正常）
    /// \return 错误码
    virtual int32_t GetFan1Status(unsigned char &status);

    /// \brief 启动/关闭光敏照明灯（单播指令）
    ///
    /// 控制选项说明： 主柜光敏照明灯（0x02：打开，0x03：关闭）， 副柜光敏照明灯（0x01: 打开，0x00：关闭）
    /// \param[in] flag 控制选项
    /// \return 错误码
    virtual int32_t EnableLamp(unsigned char flag);

    /// \brief 获取照明灯的状态 // TODO
    ///
    /// 获取照明灯的状态
    /// \param[out] status  获取照明灯的状态(0x00表示照明灯打开，0x01表示照明灯关闭)
    /// \return 错误码
    virtual int32_t GetLampStatus(unsigned char &status);

    /// \brief 控制抽屉打开或者关闭
    ///
    /// 打开抽屉的接口只会上电700ms，然后会自动断电关闭
    /// \param[in] status 抽屉状态标志（0x00：表示是关闭抽屉，0x01：表示打开抽屉）
    /// \return 错误码
    virtual int32_t EnableDrawer(unsigned char status);

    /// \brief 检测投递口门锁是否打开
    ///
    /// \param[out] status 锁状态（0x00表示是投递口门锁打开，0x01表示投递口门锁关闭）
    /// \return 错误码
    virtual int32_t GetDeliveryBoxDoorStatus(unsigned char &status);

    /// \brief 控制投递口锁具打开或者关闭
    ///
    /// \param[in] col 指定监控板号
    /// \param[in] status 锁状态（0x00表示是投递口门锁打开，0x01表示投递口门锁关闭）
    /// \return 错误码
    virtual int32_t SetDeliveryBoxDoorStatus(unsigned char status);

    /// \brief 开启投递包裹数量检测
    ///
    /// \return 错误码
    virtual int32_t EnableDeliveryBoxNumberCheck();

    /// \brief 关闭投递包裹数量检测
    /// \return 错误码
    virtual int32_t DisableDeliveryBoxNumberCheck();

    /// \brief 查询投递包裹数量
    ///
    /// \param[out] data 投递包裹的数量
    /// \return 错误
    virtual int32_t GetDeliveryBoxNumber(int32_t &data);

    /// \brief 检测投递箱是否箱满
    ///
    /// \param[out] isfull 0x00表示箱满，0x01表示箱未满
    /// \return 错误码
    virtual int32_t IsDeliveryBoxFull(unsigned char &isfull);

    /// \brief 开启对ARM板或者工控机电源控制
    ///
    /// 该接口用于开启对ARM板或者工控机电源控制
    /// \return 错误码
    virtual int32_t OpenArmAndPlcPower();

    /// \brief 关闭对ARM板或者工控机电源控制
    ///
    /// 该接口用于关闭对ARM板或者工控机电源控制
    /// \return 错误码
    virtual int32_t CloseArmAndPlcPower();

    /// \brief ARM板或者工控机正常报告指令
    ///
    /// 该接口用于每3分钟ARM板或工控机向监控板发送该指令，温控板开启3分钟检测，
    /// 如果3分钟之内没有收到，则复位ARM板或工控机的电源。
    /// \return 错误码
    virtual int32_t SetArmAndPlcReportCmd();

    /// \brief 设置监控板控制工控机电源的临界温度
    ///
    /// 该接口用于设置监控板控制工控机电源的临界温度
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetPlcPowerTemperature(int32_t temperature);

    /// \brief 查询监控板控制工控机电源的临界温度
    ///
    /// 该接口用于查询监控板控制工控机电源的临界温度
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[out] temperature 温度值
    /// \return 错误码
    virtual int32_t GetPlcPowerTemperature(int32_t &temperature);

    /// \brief 查询主控门状态
    ///
    /// 该接口用于查询主控门状态
    /// \param[in] col 指定监控板号
    /// \param[out] status 主控门状态，0x00表示主控门关闭，0x01表示主控门打开
    /// \return 错误码
    virtual int32_t GetMasterDoorStatus(unsigned char &status);

    /// \brief 打开主控门
    ///
    /// 该接口用于打开主控门
    /// \param[in] col 指定监控板号
    /// \return 错误码
    virtual int32_t OpenMasterDoor();

    /// \brief 打开锁 // TODO 添加详细说明
    ///
    /// 该接口用于打开锁
    /// \param[in] col 指定监控板号
    /// \return 错误码
    virtual int32_t OpenLock();

    /// \brief 设置空调参数
    ///
    /// 设置空调参数
    /// \param[in] opt 传入的空调的参数
    /// \param[out] outopt 传出的空调的参数信息
    /// \return 错误码
    virtual int32_t SetAirConditioningOption(const AirConditioningOption &opt, AirConditioningOption &outopt);

    /// \brief 获取空调参数
    ///
    /// 指令是针对英维克新空调的指令
    /// \param[out] option 空调的参数信息
    /// \return 错误码
    virtual int32_t GetAirConditioningOption(AirConditioningOption &option);

    /// \brief 查询空调状态
    ///
    /// \param[out] status 空调的状态信息
    /// \return 错误码
    virtual int32_t GetAirConditioningStatus(AirConditioningStatus &status);

    /// \brief 查询DHT11温湿度值
    ///
    /// 湿度值为实际数值 * 100 以百分比显示，示例：湿度值 60.34%则这里获取到的humidity为6034
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[out] temperature 温度值
    /// \param[out] humidity  湿度值
    /// \return 错误码
    virtual int32_t GetDHT11TemperatureHumidity(int32_t &temperature, int32_t &humidity);

    /// \brief 设置高温报警点
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetHighTemperatureAlarmPoint(int32_t temperature);

    /// \brief 设置低温报警点
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetLowTemperatureAlarmPoint(int32_t temperature);

    /// \brief 设置压缩机启动温度
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetCompressorStartingTemperature(int32_t temperature);

    /// \brief 设置压缩机回差温度
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetCompressorReturnTemperature(int32_t temperature);

    /// \brief 设置加热器启动温度
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetHeaterStartingTemperature(int32_t temperature);

    /// \brief 设置加热器回差温度
    ///
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] temperature 温度值
    /// \return 错误码
    virtual int32_t SetHeaterReturnTemperature(int32_t temperature);

    /// \brief 查询高温告警、柜内回风温度探头故障告警信息
    ///
    /// \param[out] temphalarm 高温告警信息（0x00：正常，0x01：告警，0xFF：无效）
    /// \param[out] tempprobealarm 柜内回风温度探头告警信息（0x00：正常，0x01：告警，0xFF：无效）
    /// \return 错误码
    virtual int32_t GetTemperatureProbeStatus(unsigned char &temphalarm, unsigned char &tempprobealarm);

    /// \brief 设置加热模块临界温度值
    ///
    /// WDF-IM-3B加热模块, 该接口用于接了加热模块的监控板设置加热模块临界温度值
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[in] th 温度上限值
    /// \param[in] tl 温度下限值
    /// \return 错误码
    virtual int32_t SetHeaterCriticalTemperature(int32_t th, int32_t tl);

    /// \brief 查询加热模块参数
    ///
    /// WDF-IM-3B加热模块, 该接口用于接了加热模块的监控板查询加热模块参数
    /// \param[out] option 加热器参数选项
    /// \return 错误码
    virtual int32_t GetHeaterOption(HeaterOption &option);

    /// \brief 读取加热模块环境温度
    ///
    /// WDF-IM-3B加热模块, 该接口用于接了加热模块的监控板读取加热模块环境温度
    /// 温度值为实际数值 * 100，示例：实际温度为38.32摄氏度，则获取到的temperature为3832
    /// \param[out] temperature 环境温度值
    /// \return 错误码
    virtual int32_t GetHeaterEnviromentTemperature(int32_t &temperature);

    /// \brief 启动/关闭加热器
    ///
    /// WDF-IM-3B加热模块, 该接口用于接了加热模块的监控板启动/关闭加热器
    /// \param[in] flag 启动标志 为01H时，启动加热器，为00H时，关闭加热器
    /// \return 错误码
    virtual int32_t EnableHeater(unsigned char flag);

    /// \brief 查询加热模块软件版本号
    ///
    /// WDF-IM-3B加热模块, 该接口用于接了加热模块的监控板查询加热模块软件版本号
    /// \param[in] col 指定监控板号
    /// \param[out] version 固件版本号 示例"v1.0.1"
    /// \return 错误码
    virtual int32_t GetHeaterFirmwareVersion(char *version);
};

}  // namespace zlbase
}  // namespace zl

#endif  // ZLBASE_DEVICE_IMONITORCONTROLBOARD_H_